package com.xiashitech.apiservice.api;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.xiashitech.apiservice.Constants.ErrorCode;
import com.xiashitech.apiservice.dto.ApiService;
import com.xiashitech.apiservice.service.IApiMetadataService;
import com.xiashitech.apiservice.service.IUserInfoService;
import com.xiashitech.interfaces.agent.dto.api.ApiRequest;
import com.xiashitech.interfaces.agent.dto.api.ApiResponse;
import com.xiashitech.interfaces.apiservice.dto.user.UserInfoRequest;
import com.xiashitech.interfaces.apiservice.dto.user.UserInfoResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * api元数据保存controller，将agent获取到的api元数据保存到openmetadata中，或者从openmedata中查询检索api元数据
 */
@Controller
@RequestMapping(value = "/v1/agent")
@RequiredArgsConstructor(onConstructor =@_(@Autowired))
public class ApiMetadataController {
    private static final Log log = LogFactory.get();

    private final IApiMetadataService apiMetadataService;

    final static ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10,
            30, TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(1000));

    @RequestMapping(value = "/syncApisToOpenMetadata", method = RequestMethod.POST, produces = "application/json;charset=UTF-8" ,consumes = "application/json;charset=UTF-8")
    @ResponseBody
    public ApiResponse syncApisToOpenMetadata(@RequestBody ApiRequest apiRequest) {
        if(apiRequest == null || apiRequest.getApis() == null || apiRequest.getApis().size() == 0 || apiRequest.getSystemId() == null || "".equals(apiRequest.getSystemId())) {
            return ApiResponse.builder().code(ErrorCode.RESULT_1002.getCode()).message(ErrorCode.RESULT_1002.getMessage()).build();
        }
        //return apiMetadataService.syncApisToOpenMetadata(apiRequest);
        submitTask(apiRequest, "syncApisToOpenMetadata");
        return ApiResponse.builder().code(ErrorCode.RESULT_1001.getCode()).message(ErrorCode.RESULT_1001.getMessage()).build();
    }

    @RequestMapping(value = "/generateDesenseParam", method = RequestMethod.POST, produces = "application/json;charset=UTF-8" ,consumes = "application/json;charset=UTF-8")
    @ResponseBody
    public ApiResponse generateDesenseParam(@RequestBody ApiRequest apiRequest) {
        if(apiRequest == null || apiRequest.getDesenseParam() == null || apiRequest.getDesenseParam().getApiName() == null || apiRequest.getDesenseParam().getSystem() == null || apiRequest.getDesenseParam().getDesenseParam() == null || apiRequest.getDesenseParam().getDesenseParam().size() == 0) {
            return ApiResponse.builder().code(ErrorCode.RESULT_1002.getCode()).message(ErrorCode.RESULT_1002.getMessage()).build();
        }
        // return apiMetadataService.generateDesenseParam(apiRequest);
        submitTask(apiRequest,"generateDesenseParam");
        return ApiResponse.builder().code(ErrorCode.RESULT_1001.getCode()).message(ErrorCode.RESULT_1001.getMessage()).build();
    }
    public static void submitTask(ApiRequest apiRequest, String methdName) {
        executor.submit(() -> {
            try {
                ApiResponse resp = null;
                IApiMetadataService mdService = SpringUtil.getBean(IApiMetadataService.class);
                if ("syncApiParamsToOpenMetadata".equals(methdName)) {
                    resp = mdService.syncApiParamsToOpenMetadata(apiRequest);
                } else if ("generateDesenseParam".equals(methdName)) {
                    resp = mdService.generateDesenseParam(apiRequest);
                } else if ("syncApisToOpenMetadata".equals(methdName)) {
                    resp = mdService.syncApisToOpenMetadata(apiRequest);
                } else {
                    // 不存在指定方法
                }
                log.info("ApiMetadataController submitTask: " + methdName + ", request: " + System.identityHashCode(apiRequest) + ", resp: " + resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }


    @PostMapping(value = "/syncApiParamsToOpenMetadata")
    @ResponseBody
    public ApiResponse syncApiParamsToOpenMetadata(@RequestBody ApiRequest apiRequest) {
        if(apiRequest == null || apiRequest.getApis() == null || apiRequest.getApis().size() == 0 || apiRequest.getSystemId() == null || "".equals(apiRequest.getSystemId())) {
            return ApiResponse.builder().code(ErrorCode.RESULT_1002.getCode()).message(ErrorCode.RESULT_1002.getMessage()).build();
        }
        //return apiMetadataService.syncApiParamsToOpenMetadata(apiRequest);
        submitTask(apiRequest,"syncApiParamsToOpenMetadata");
        return ApiResponse.builder().code(ErrorCode.RESULT_1001.getCode()).message(ErrorCode.RESULT_1001.getMessage()).build();
    }
    @RequestMapping(value = "/getApiByFQN", method = RequestMethod.GET)
    @ResponseBody
    public JSONObject getApiByFQN(@RequestParam("fqn") String fqn)
    {
        return apiMetadataService.getApiByFQN(fqn);

    }
}
